/**
 * Function 实例的 bind() 方法创建一个新函数，当调用该新函数时，它会调用原始函数并将其 this 关键字设置为给定的值，同时，还可以传入一系列指定的参数，这些参数会插入到调用新函数时传入的参数的前面。
 * @param {*} context
 * @param {*} args 这里的参数要和最后调用的合并到一起
 */
Function.prototype.myBind = function (context, ...args) {
  // 校验调用者
  if (typeof this != "function") throw new TypeError("调用者必须是一个函数！");
  // 处理类型
  context = context == null ? window : Object(context);

  // 添加属性并
  const _pro = Symbol("p");
  context[_pro] = this;

  return function (...rest) {
    // 合并参数
    const prams = [...args, ...rest];
    let result = context[_pro](...prams);
    // delete context[_pro]; // 加上删除就bind返回的方法只能执行一次，但是官方的可以多次
    return result;
  };
};

// eg
function fn(arg, arg2) {
  console.log("arg2", arg, arg2);
  console.log(this);
}

let fnb = fn.myBind({}, [1], 2);
fnb();
fnb();

let fnb1 = fn.myBind({}, [1], 3);
fnb1();
